#include <memory>
#include <vector>
#include <algorithm>

using namespace std;

class Foo {
    public:
        Foo sorted() &&;            // 可用于可改变的右值
        Foo sorted() const &;       // 可用于任何类型的 Foo
        /**
         * 如果我们定义两个或两个以上具有相同名字和相同参数列表的成员函数
         * 就必须对所有函数都加上引用限定符，或者所有都不加
         */
        using Comp = bool(const int&, const int&);
        Foo sorted(Comp*) {}        // 正确：不同的参数列表
        Foo sorted(Comp*) const {}  // 正确：两个版本都没有引用限定符

        // Foo 的其他成员的定义
    private:
        vector<int> data;
};

// 本对象为右值，因此可以原址排序（本对象没有其他用户）
inline Foo Foo::sorted() &&
{
    sort(data.begin(), data.end());
    return *this;
}

// 本对象是 const 或是一个左值，哪种情况我们都不能对其进行原址排序（需要拷贝本对象）
inline Foo Foo::sorted() const & {
    Foo ret(*this);                         // 拷贝一个副本
    sort(ret.data.begin(), ret.data.end()); // 排序副本
    return ret;                             // 返回副本
}

int main()
{
    Foo &retFoo();
    Foo retVal();

    retVal().sorted();  // retVal() 返回一个右值，调用 Foo::sorted() &&
    retFoo().sorted();  // retFoo() 返回一个左值，调用 Foo::sorted() const &
}